package framework.serialize.kyro;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import framework.serialize.Serializer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public class KyroSerializer implements Serializer {


    private final ThreadLocal<Kryo> kryoThreadLocal = ThreadLocal.withInitial(() -> {
        Kryo kryo = new Kryo();
        return kryo;
    });

    @Override
    public <T> byte[] serialize(T obj) {
        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
             Output output = new Output(byteArrayOutputStream)) {
            kryoThreadLocal.get().writeObject(output, obj);
            kryoThreadLocal.remove();
            return output.toBytes();
        } catch (Exception ex) {
            throw new RuntimeException("kyro Serialization failed");
        }
    }

    @Override
    public <T> T deserialize(byte[] bytes, Class<T> clazz) {
        try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
             Input input = new Input(byteArrayInputStream)) {
            T t = kryoThreadLocal.get().readObject(input, clazz);
            kryoThreadLocal.remove();
            return t;
        } catch (Exception ex) {
            throw new RuntimeException("kyro Deserialization failed");
        }
    }
}
